package async

import "fmt"

type PromiseResult[T any] struct {
	Result T
	Error  error
}

type PromiseChan[T any] struct {
	ch chan PromiseResult[T]
}

func Promise[T any](f func() (T, error)) (result *PromiseChan[T]) {
	result = &PromiseChan[T]{ch: make(chan PromiseResult[T])}
	go func() {
		defer close(result.ch)
		defer func() {
			if err := recover(); err != nil {
				result.ch <- PromiseResult[T]{Error: fmt.Errorf("%v", err)}
			}
		}()
		ret, err := f()
		result.ch <- PromiseResult[T]{Result: ret, Error: err}

	}()
	return

}

func (p *PromiseChan[T]) Then(f func(resolve T, err error)) {
	data := <-p.ch
	f(data.Result, data.Error)
}
